﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace AgvDispatchSystem
{
    public class AgvManager
    {
        List<Agv> agvList = new List<Agv>();
        bool[] _trafficControl = new bool[56];
        IDriver _driver;
        Timer _cycleTimer = new Timer(200);
        public AgvManager()
        {
            InitialAgv();
            _cycleTimer.AutoReset = true;
            _cycleTimer.Elapsed += _cycleTimer_Elapsed;
            _cycleTimer.Start();
        }

        private void _cycleTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            byte[] sendBuffer = new byte[11];
            byte[] recvBuffer = new byte[11];
            byte[] sendCheckBuffer = new byte[9];
            byte[] recvCheckBuffer = new byte[9];
            byte[] trafficControlBuffer = new byte[7];

            trafficControlBuffer = BitArrayToByteArray(_trafficControl);

            sendBuffer[0] = 0xA9;
            sendBuffer[1] = 0xC1;
            sendBuffer[2] = trafficControlBuffer[0];
            sendBuffer[3] = trafficControlBuffer[1];
            sendBuffer[4] = trafficControlBuffer[2];
            sendBuffer[5] = trafficControlBuffer[3];
            sendBuffer[6] = trafficControlBuffer[4];
            sendBuffer[7] = trafficControlBuffer[5];
            sendBuffer[8] = trafficControlBuffer[6];
            Array.Copy(sendBuffer, sendCheckBuffer, 9);//复制之前的数组
            sendBuffer[9] = CalculateAdd(sendCheckBuffer);
            sendBuffer[10] = 0x05;

            recvBuffer = _driver.WriteAndRead(sendBuffer);//发送并接收
            //Array.Copy(recvBuffer, recvCheckBuffer, 9);
            //if (recvCheckBuffer[1] == 0xB2 && recvBuffer[9] == CalculateAdd(recvCheckBuffer))
            //{

            //}
        }

        public byte[] BitArrayToByteArray(bool[] bits)
        {
            byte[] ret = new byte[(bits.Length - 1) / 8 + 1];
            bits.CopyTo(ret, 0);
            return ret;
        }

        public void InitialAgv()
        {
            foreach (var item in agvList)//C2-B2
            {
                item.OnAgvControlChanged += Item_OnAgvControlChanged;//绑定agv控制更改事件
                item.OnAgvTrafficControlChanged += Item_OnAgvTrafficControlChanged;//监听agv交通管制变化
            }
        }

        private void Item_OnAgvTrafficControlChanged(object sender)
        {
            Agv agv = sender as Agv;
            if (agv!=null)
            {
                int index = agv.ID - 1;
                _trafficControl[index] = agv.TrafficControl;
            }
        }

        private void Item_OnAgvControlChanged(object sender, AgvControlChangedEventArgs e)
        {
            byte[] sendBuffer = new byte[11];
            byte[] recvBuffer = new byte[11];
            byte[] sendCheckBuffer = new byte[9];
            byte[] recvCheckBuffer = new byte[9];

            sendBuffer[0] = 0xA9;
            sendBuffer[1] = 0xC2;
            sendBuffer[2] = e.SetControlByte;
            sendBuffer[3] = e.SetSpeedByte;
            sendBuffer[4] = e.SetTaskByte;
            sendBuffer[5] = e.SetSubTaskByte;
            sendBuffer[6] = 0x00;
            sendBuffer[7] = 0x00;
            sendBuffer[8] = e.ID;
            Array.Copy(sendBuffer, sendCheckBuffer, 9);//复制之前的数组
            sendBuffer[9] = CalculateAdd(sendCheckBuffer);
            sendBuffer[10] = 0x05;

            recvBuffer = _driver.WriteAndRead(sendBuffer);//发送并接收
            Array.Copy(recvBuffer, recvCheckBuffer, 9);
            if (recvCheckBuffer[1] == 0xB2 && recvBuffer[9] == CalculateAdd(recvCheckBuffer))
            {
                //校验通过
                Agv agv = sender as Agv;
                if (agv != null)
                {
                    byte[] rfidBuffer = new byte[2];
                    Array.Copy(recvBuffer, 4, rfidBuffer, 0, 2);
                    agv.UpdataStatus(recvBuffer[2], recvBuffer[3], BitConverter.ToUInt16(rfidBuffer, 0), recvBuffer[6], rfidBuffer[7], recvBuffer[8]);
                }
            }
        }

        /// <summary>
        /// 累加和校验
        /// </summary>
        /// <param name="buffer">待校验字节数组</param>
        /// <returns>校验结果</returns>
        public byte CalculateAdd(byte[] buffer)//取低八位
        {
            int cks = 0;
            foreach (byte item in buffer)
            {
                cks = (cks + item) % 0xffff;
            }
            //byte bt = (byte)((cks & 0xff00) >> 8);//取校验和高8位
            byte bt = (byte)(cks & 0xff);//取校验和低8位
            return bt;
        }
    }
}
